package com.example.java_gobang.api;

import com.example.java_gobang.model.MatchRequest;
import com.example.java_gobang.model.MatchResponse;
import com.example.java_gobang.game.Matcher;
import com.example.java_gobang.game.OnlineUserManager;
import com.example.java_gobang.model.User;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.socket.CloseStatus;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketMessage;
import org.springframework.web.socket.WebSocketSession;
import org.springframework.web.socket.handler.TextWebSocketHandler;

@Slf4j
@Component
public class MatchAPI extends TextWebSocketHandler {
    private ObjectMapper objectMapper = new ObjectMapper();
    @Autowired
    private OnlineUserManager onlineUserManager;

    @Autowired
    private Matcher matcher;

    @Override
    public void afterConnectionEstablished(WebSocketSession session) throws Exception {
        User user = (User) session.getAttributes().get("user");
        if (user == null) {
            MatchResponse matchResponse = new MatchResponse();
            matchResponse.setOk(false);
            matchResponse.setReason("用户未登录！");
            session.sendMessage(new TextMessage(objectMapper.writeValueAsBytes(matchResponse)));
            session.close();
            return;
        }
        if (onlineUserManager.getFromGameHall(user.getUserId()) != null || onlineUserManager.getFromGameRoom(user.getUserId()) != null) {
            MatchResponse matchResponse = new MatchResponse();
            matchResponse.setOk(true);
            matchResponse.setMessage("repeatConnection");
            session.sendMessage(new TextMessage(objectMapper.writeValueAsBytes(matchResponse)));
            session.close();
            return;
        }
        onlineUserManager.enterGameHall(user.getUserId(), session);
        log.info("玩家" + user.getUsername() + "进入游戏大厅!");
    }

    @Override
    public void handleMessage(WebSocketSession session, WebSocketMessage<?> message) throws Exception {
        User user = (User) session.getAttributes().get("user");
        String payload = (String) message.getPayload();
        MatchRequest matchRequest = objectMapper.readValue(payload, MatchRequest.class);
        MatchResponse matchResponse = new MatchResponse();
        if (matchRequest.getMessage().equals("startMatch")){
            matcher.add(user);
            matchResponse.setOk(true);
            matchResponse.setMessage("startMatch");
        } else if (matchRequest.getMessage().equals("stopMatch")) {
            matcher.remove(user);
            matchResponse.setOk(true);
            matchResponse.setMessage("stopMatch");
        } else {
            matchResponse.setOk(false);
            matchResponse.setReason("非法的匹配请求!");
        }
        session.sendMessage(new TextMessage(objectMapper.writeValueAsString(matchResponse)));
    }

    @Override
    public void handleTransportError(WebSocketSession session, Throwable exception) throws Exception {
        User user = (User) session.getAttributes().get("user");
        WebSocketSession webSocketSession = onlineUserManager.getFromGameHall(user.getUserId());
        if (webSocketSession == session) {
            onlineUserManager.exitGameHall(user.getUserId());
            //如果玩家正在匹配中，而websocket连接断开了，移除玩家
            matcher.remove(user);
            log.info("玩家" + user.getUsername() + "连接异常!");
        }
    }

    @Override
    public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {
        User user = (User) session.getAttributes().get("user");
        WebSocketSession webSocketSession = onlineUserManager.getFromGameHall(user.getUserId());
        if (webSocketSession == session) {
            onlineUserManager.exitGameHall(user.getUserId());
            //如果玩家正在匹配中，而websocket连接断开了，移除玩家
            matcher.remove(user);
            log.info("玩家" + user.getUsername() + "离开游戏大厅!");
        }
    }
}
